package com.wstuo.common.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.Charset;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy;
import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.core.pattern.RegexReplacement;
public class LogUtils {
	
	/**
	 * 获取操作日志的Logger对象
	 * @param filePath 文件路径 
	 * @param loginName 登录名
	 * @param opt 操作项
	 * @param optCode 操作码
	 * @param resInfo 资源信息
	 * @param resCode 资源码
	 * @param date 日期
	 * @param cosTime 耗时
	 * @param resId 资源id
	 * @param loggerName logger名字
	 * @param header 列头
	 * @return
	 */
	public static Logger getUserOptLogger(String filePath,String loginName,
			String optCode,String resCode,String date,Long cosTime,String resId,String loggerName){
		String cosSecond = String.format("%,.3f", cosTime/1000.0);//毫秒化作为秒（保留三位小数并用逗号分隔符）
		ThreadContext.put("loginName", loginName);
		ThreadContext.put("optCode", optCode);
		ThreadContext.put("resCode", resCode);
		ThreadContext.put("date", date);
		ThreadContext.put("cosTime", cosSecond);
		ThreadContext.put("resId",	resId);
		 Logger logger = getCommonLogger(filePath,loggerName, PatternLayout.USEROPTLOG_CONVERSION_PATTERN,"csv");
         return logger;
	}
	/**
	 * 获取在线用户日志的Logger对象
	 * @param filePath  文件路径
	 * @param loginName  登录名
	 * @param loginOrlogout  
	 * @param date 现在的时间
	 * @param sessionId 回话id
	 * @param loggerName logger名字（请用自定义名字+tenantId）
	 * @param header 列头
	 * @return
	 */
	public static Logger getOnlineLogger(String filePath,String loginName,String loginOrlogout,String date,String sessionId,String loggerName){
			ThreadContext.put("loginName", loginName);
			ThreadContext.put("loginOrlogout", loginOrlogout);
			ThreadContext.put("date", date);
			ThreadContext.put("sessionId", sessionId);
			Logger logger = getCommonLogger(filePath,loggerName, PatternLayout.USERONLINELOG_CONVERSION_PATTERN,"csv");
		return logger;
	}
	
	/**
	 * 获取错误日志的Logger对象
	 * @param filePath 文件路径
	 * @param loggerName logger名字（请用自定义名字+tenantId）
	 * @param loginName 登陆名
	 * @param date 日期
	 * @param methodName 方法名
	 * @param resourceName 资源名
	 * @param dtoId 
	 * @param message 错误信息
	 * @param errCause 错误原因
	 * @return
	 */
	public static Logger getOptErrorLog(String filePath,String loggerName,String loginName,String date,String methodName
			,String resourceName,String message,String errCause,String resId){
		ThreadContext.put("loginName",loginName);
		ThreadContext.put("date",date);
		ThreadContext.put("methodName",methodName);
		ThreadContext.put("resourceName",resourceName);
		ThreadContext.put("message",message);
		ThreadContext.put("errCause",errCause);
		ThreadContext.put("resId", resId);
		Logger logger = getCommonLogger(filePath,loggerName, PatternLayout.USEROPTERRORLOG_CONVERSION_PATTERN,"txt");
		return logger;
	}
	
	/**
	 * 获取栈中的异常信息
	 * @param e 参数Exception e
	 * @return String 栈中的异常信息
	 */
	public static String getStackTrace(Throwable e) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw, true);
		e.printStackTrace(pw);
		pw.flush();
		sw.flush();
		return sw.toString();
	}
	
	
	/**
	 * 日志公共模块
	 * @param filePath  文件路径
	 * @param loggerName logger名字
	 * @param pattern 内容显示样式,自定义样式请在org.apache.logging.log4j.core.layout.PatternLayout.java 定义
	 * @param header 列头
	 * @return
	 */
	private static Logger getCommonLogger(String filePath,String loggerName,String pattern,String extension) {
		final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
         final Configuration config = ctx.getConfiguration();
         RegexReplacement replace = null;//A Regex replacement String.
         Charset charset = Charset.defaultCharset();//The character set.
         boolean alwaysWriteExceptions = false;// If "true" (default) exceptions are always written even if the pattern contains no exception tokens.
         boolean noConsoleNoAnsi = false;//If "true" (default is false) and System.console() is null, do not output ANSI escape codes
         String header = null;
         String footer = null;//The footer to place at the bottom of the document, once.
         
		//默认文本显示方式
         Layout layout = PatternLayout.createLayout(pattern, config, replace,
       		  charset,alwaysWriteExceptions, noConsoleNoAnsi, header, footer);
         //html显示方式
//         HtmlLayout htmlLayout = HtmlLayout.createLayout(false, "logfortest", "text/html", charset, "14", "宋体");
         String filePattern = filePath.substring(0,filePath.lastIndexOf("."))+"-%d."+extension+".zip";//昨天日志的文件名
        String appenderName = "RollingFileAppenderName";//appender的名字
        TriggeringPolicy policy = TimeBasedTriggeringPolicy.createPolicy("1", "true");
   		RolloverStrategy strategy = DefaultRolloverStrategy.createStrategy("1", "2", "min", "5", config);
   		Appender appender = RollingFileAppender.createAppender
           		(filePath,filePattern, null, appenderName, null, null,
           				null, policy , strategy , layout, null, null,
           				null, null, config);
  		appender.start();
         
         config.addAppender(appender);
         
         
         AppenderRef ref = AppenderRef.createAppenderRef(appenderName, null, null);
         AppenderRef[] refs = new AppenderRef[] {ref};
       
         String additivity = "false";//True if additive, false otherwise.
         Level level = Level.INFO;  //The Level to be associated with the Logger.
         String includeLocation = "true"; //whether location should be passed downstream
         AppenderRef[] appenderRefs = refs; // An array of Appender names.
         Property[] properties = null; //Properties to pass to the Logger.
         Configuration configuration = config; // The Configuration.
         Filter filter = null;  //A Filter.
         
         LoggerConfig loggerConfig = LoggerConfig.createLogger(additivity, level, loggerName,
       		  includeLocation, appenderRefs, properties, configuration, filter );
         loggerConfig.addAppender(appender, null, null);
         config.addLogger(loggerName, loggerConfig);
         ctx.updateLoggers();
         Logger logger = ctx.getLogger(loggerName);
		return logger;
	}
}
